<?php
require_once('ngdom.database.php');
$ngdom_user = null;
$ngdom_game = 'default';

function ngdom_set_game($game) {
	global $ngdom_game;
	$ngdom_game = $game;
}
function ngdom_meta_data() {
	global $ngdom_game;
	?>
	<meta name="apple-mobile-web-app-capable" content="yes" />
	<meta name="apple-mobile-web-app-status-bar-style" content="black" />
	<meta name="viewport" content="user-scalable=no, initial-scale=1.0" />
	<link rel="apple-touch-icon" href="game/<?php echo $ngdom_game; ?>/apple-touch-icon.png" />
	<link rel="apple-touch-startup-image" href="game/<?php echo $ngdom_game; ?>/startup.png" />
	<?php
}
function ngdom_js_data() {
	global $ngdom_user, $ngdom_game;
	if ($authorized = ngdom_authorize_user() && $savedata = ngdom_load_game())
		$savedata = $savedata == 'NOSAVE' ? 'false' : "'".$savedata."'";
	else
		$savedata = 'false';
		
	$authorized = $authorized ? 'true' : 'false';
	
	echo "<script type=\"text/javascript\">
	var ngdomData = {
		game: '$ngdom_game',
		savedata: $savedata, 
		authorized: $authorized
		};
</script>";
}
function ngdom_authorize_user() {
	global $ngdom_user;
	if (!empty($ngdom_user) && !empty($ngdom_user->user_email) && !empty($ngdom_user->secret)) return true;
	
	$auth = $_COOKIE['ngdom-auth'];
	if (empty($auth)) return false;
	
	$pieces = explode('|', $auth);
	if (count($pieces) != 3) return false;
	
	list($login, $timestamp, $token) = $pieces;
	$user = ngdom_db_getrow("select * from ngdom_users where user_email='%s'", $login);
	if (!$user || empty($user->secret)) return false;
	
	$check_token = ngdom_generate_user_token($user, $timestamp);
	$authorized = $token == $check_token;
	
	if ($authorized) $ngdom_user = $user;
	return $authorized;
}
function ngdom_save_game($savedata = null, $saveslot = 1) {
	global $ngdom_user, $ngdom_game;
	if (!ngdom_authorize_user()) return false;
	
	if ($savedata == null) $savedata = get_post_var('data');
	$result = ngdom_db_query(
		"update ngdom_save set savedata='%s', last_played=now() where user_id=%u and game='%s' and slot=%u", 
		$savedata, $ngdom_user->id, $ngdom_game, $saveslot
		);
	if ($result === 0) {
		$result = ngdom_db_query(
			"insert into ngdom_save (user_id, game, slot, savedata, created, last_played) ".
			"values (%u, '%s', %u, '%s', now(), now())", 
			$ngdom_user->id, $ngdom_game, $saveslot, $savedata
			);
	}
	if (!$result || ngdom_is_db_error($result)) return false;
	
	return true;
}
function ngdom_load_game($saveslot = 1) {
	global $ngdom_user, $ngdom_game;
	if (!ngdom_authorize_user()) return false;
	
	$savedata = ngdom_db_getval("select savedata from ngdom_save where user_id=%u and game='%s' and slot=%u",
		$ngdom_user->id, $ngdom_game, $saveslot);
		
	$savedata = stripslashes($savedata);
	return empty($savedata) ? 'NOSAVE' : $savedata;
}
function ngdom_delete_game($saveslot = 1) {
	global $ngdom_user, $ngdom_game;
	if (!ngdom_authorize_user()) return false;
	
	$result = ngdom_db_query(
		"update ngdom_save set savedata='' where user_id=%u and game='%s' and slot=%u", $ngdom_user->id, $ngdom_game, $saveslot
		);
		
	return $result === 1;
}
function ngdom_generate_user_token($user, $timestamp) {
	$pass_fragment = substr($user->user_pass, 0, strlen($user->user_pass) / 2);
	
	$key = $user->user_pass.'&'.$user->secret;
	$data = "user_email={$user->user_email}&user_pass_frag=$pass_fragment&timestamp=$timestamp";
	
	return hash_hmac('sha1', $data, $key);
}
function ngdom_generate_user_auth_cookie($user) {
	$login = $user->user_email;
	$timestamp = time();
	$token = ngdom_generate_user_token($user, $timestamp);
	return implode('|', array($login, $timestamp, $token));
}
function ngdom_user_login($email = null, $pass = null) {
	global $ngdom_user;
	
	require('PasswordHash.php');
	$hasher = new PasswordHash(8, false);
	
	if ($email == null) $email = get_post_var('user_email');
	if ($pass == null) $pass = get_post_var('user_pass');
	
	if (!preg_match('/^[a-zA-Z0-9_\@\.]{5,255}$/', $email))
		return false; //fail('Invalid username');
	
	if (strlen($pass) > 72)
		return false; //fail('The supplied password is too long');
	
	$user = ngdom_db_getrow("select * from ngdom_users where user_email='%s'", $email);
	if (!$user || empty($user->user_pass)) return false;
	
	$result = ($hasher->CheckPassword($pass, $user->user_pass));
	unset($hasher);
	
	if ($result) {
		$expires = get_post_var('remember') == 'Yes' ? time()+60*60*24*365 : 0;
		setcookie('ngdom-auth', ngdom_generate_user_auth_cookie($user), $expires);
		header('Content-type: text/plain');
		$ngdom_user = $user;
		return ngdom_load_game();
	}
	else
		return false;
}
function ngdom_create_account($email = null, $pass = null) {
	require('PasswordHash.php');
	$hasher = new PasswordHash(8, false);
	
	if ($email == null) $email = get_post_var('user_email');
	if ($pass == null) $pass = get_post_var('user_pass');
	
	if (empty($email) || empty($pass)) return false;
	if (!preg_match('/^[a-zA-Z0-9_\@\.]{5,255}$/', $email))
		return ngdom_js_error('There was a problem with your email address. It may have been used before.');
	if (strlen($pass) > 72)
		return ngdom_js_error('We regret to inform you of the overabundance of your password. Please try a smaller one.');
	
	$hash = $hasher->HashPassword($pass);
	if (strlen($hash) < 20)
		return ngdom_js_error('Something is seriously wrong with your password. Try another?');
	unset($hasher);

	$result = ngdom_db_query('insert into ngdom_users (user_email, user_pass, secret, created, last_played) '
						.'values ("%s", "%s", null, now(), now())', $email, $hash);
						
	if (ngdom_is_db_error($result) && $result['errno'] == 1062) {
		return ngdom_js_error('There was a problem with your email address. It may have been used before.');
	}
	elseif (ngdom_is_db_error($result)) {
		return ngdom_js_error('There was an unknown problem and your account could not be created. Please try again later!');
	}
	
	$try_secret = true;
	while ($try_secret) {
		$secret = rand_str(128);
		$result = ngdom_db_query('update ngdom_users set secret="%s" where user_email="%s"', $secret, $email);
		//keep randomizing until unique key is found
		$try_secret = (ngdom_is_db_error($result) && $result['errno'] == 1062);
	}
	
	$user = ngdom_db_getrow("select * from ngdom_users where user_email='%s'", $email);
	
	setcookie('ngdom-auth', ngdom_generate_user_auth_cookie($user));
	return true;
}
function ngdom_reset_password($email = null) {
	if ($email == null) $email = get_post_var('user_email');
	
	$user = ngdom_db_getrow("select * from ngdom_users where user_email='%s'", $email);
	if (!$user) return false;
	
	$try_token = true;
	
	while ($try_token) {
		$reset_token = rand_str(32);
		$result = ngdom_db_query('update ngdom_users set pass_reset_token="%s", pass_reset_time=now() where user_email="%s"', 
			$reset_token, $email);
		$try_token = (ngdom_is_db_error($result) && $result['errno'] == 1062);
	}
	
	if (!ngdom_is_db_error($result)) {
		$reset_token_url = 'http://'.$_SERVER["SERVER_NAME"].
			substr($_SERVER["REQUEST_URI"], 0, strrpos($_SERVER["REQUEST_URI"], '/') + 1).
			'?reset='.$reset_token;
		ngdom_send_mail($user->user_email, 'Password Reset Request', 
			"Hello! \r\n\r\n".
			"A password reset for the game Cellarfold was requested for this email address. ".
			"If you would like to complete the password reset, click the link below. ".
			"If not, simply ignore this email. \r\n\r\n".
			$reset_token_url." \r\n\r\n".
			"Pleasant Dreams...", 
			'cellarfold');
		return true;
	}
	else
		return false;
}
function ngdom_change_password($reset_token = null, $new_pass = null) {
	require('PasswordHash.php');
	$hasher = new PasswordHash(8, false);
	
	if ($reset_token == null) $reset_token = get_post_var('reset_token');
	if ($new_pass == null) $new_pass = get_post_var('new_pass');
	
	if (empty($reset_token) || empty($new_pass)) return false;
	if (strlen($new_pass) > 72)
		return false; //fail('The new password is too long');
	
	$user = ngdom_db_getrow('select * from ngdom_users where pass_reset_token="%s"', $reset_token);
	if (!$user) return false;
	
	if (time() - strtotime($user->pass_reset_time) > 60 * 60) //1 hour
		return false;
		
	$hash = $hasher->HashPassword($new_pass);
	if (strlen($hash) < 20)
		return false; //fail('Failed to hash new password');
	unset($hasher);
	
	$result = ngdom_db_query('update ngdom_users set user_pass="%s", pass_reset_token=null, pass_reset_time=null '.
		'where pass_reset_token="%s"', $hash, $reset_token);
		
	return !ngdom_is_db_error($result);
}
function ngdom_js_error($message) {
	return 'ERROR:'.$message;
}
function ngdom_send_mail($to, $subject, $message, $from = '') {
	if (empty($from)) $from = "system@".preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']));
	else if (strpos($from, '@') === false) $from .= '@'.preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']));
	$headers = "From: $from\r\nX-Mailer: php";
	
	return @mail($to, $subject, $message, $headers);
}
function rand_str($length = 32, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890') {
    $chars_length = (strlen($chars) - 1);
    $string = $chars{rand(0, $chars_length)};
   
    for ($i = 1; $i < $length; $i = strlen($string))
    {
        $r = $chars{rand(0, $chars_length)};
        if ($r != $string{$i - 1}) $string .=  $r;
    }
	
    return $string;
}
function get_post_var($var)
{
	$val = $_POST[$var];
	if (get_magic_quotes_gpc())
		$val = stripslashes($val);
	return $val;
}
?>